<template>
  <div>
    <el-dialog
      :title="showTitle"
      :visible="showDialog"
      :before-close="beforeClose"
    >
      <!-- 关闭dialog除了调用beforeclose之外，还可以调用@close事件，直接等于cancel，相当于和点击取消按钮一样 -->
      <el-form
        ref="addDept"
        :model="FormData"
        :rules="rules"
        label-width="100px"
        label-position="left"
      >
        <el-form-item label="部门名称" prop="name">
          <el-input
            v-model="FormData.name"
            placeholder="1-50个字符"
            style="width: 80%"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input
            v-model="FormData.code"
            placeholder="1-50个字符"
            style="width: 80%"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select
            v-model="FormData.manager"
            style="width: 80%"
            placeholder="请选择"
            @focus="getUserSimple"
          >
            <el-option
              v-for="item in peoples"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input
            v-model="FormData.introduce"
            type="textarea"
            placeholder="1-300个字符"
            style="width: 80%"
            :cols="3"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <!-- 底部按钮 dialog中有专门的插槽来放置 -->、
      <el-row slot="footer" type="flex" justify="center">
        <el-col :span="6">
          <el-button size="small" @click="cancel">取消</el-button>
          <el-button type="primary" size="small" @click="submitForm">
            确定
          </el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
import {
  getDepartments,
  addDepartments,
  updateDepartments,
  getDepartDetail
} from '@/api/departments'
import { getUserSimple } from '@/api/employees'
export default {
  props: {
    showDialog: {
      type: Boolean,
      default: false
    },
    treeNode: {
      // 要校验是否与同级部门下的名字重复 - 先获取到当前部门的节点内容（通过父组件传入） - 获取最新的部门数据 - 筛选出当前部门的id与子部门的pid重复的部门 - 判断其中是否有部门的name与当前输入的value相同 - 相同，调用callback传入一个错误对象 - 没有相同的，通过校验，调用callback
      type: Object,
      default: null
    }
  },
  data() {
    // 自定义校验规则
    const checkNameRepeat = async (rule, value, callback) => {
      // 首先要获取最新的组织架构数据，调用api
      let isRepeat = false
      const { depts } = await getDepartments()
      if (this.showTitle === '新增部门') {
        // 或者this.treeNode.id 存在
        isRepeat = depts
          .filter((item) => item.pid === this.treeNode.id)
          .some((item) => item.name === value)
      } else {
        // 从筛选出来的重复的中剔除掉它自己
        isRepeat = depts
          .filter(
            (item) =>
              item.pid === this.treeNode.id && item.id !== this.treeNode.id
          )
          .some((item) => item.name === value)
      }
      isRepeat
        ? callback(new Error(`当前部门下已存在${value}部门`))
        : callback()
    }
    const checkCodeRepeat = async (rule, value, callback) => {
      let isRepeat = false
      const { depts } = await getDepartments()
      if (this.showTitle === '新增部门') {
        isRepeat = depts.some((item) => item.code === value && value !== '') // 加上value !== ''是因为历史记录的部门中可能有的部门code为空
      } else {
        isRepeat = depts
          .filter((item) => item.id !== this.treeNode.id)
          .some((item) => item.code === value && value !== '')
      }

      isRepeat
        ? callback(new Error(`组织架构下已存在${value}编码`))
        : callback()
    }
    return {
      FormData: {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      },
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          { min: 1, mix: 50, message: '长度为1-50', trigger: 'blur' },
          { validator: checkNameRepeat, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          { min: 1, mix: 50, message: '长度为1-50', trigger: 'blur' },
          { validator: checkCodeRepeat, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'blur' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { min: 1, mix: 300, message: '长度为1-300', trigger: 'blur' }
        ]
      }, // rules是一个对象，里面式key:数组
      peoples: []
    }
  },
  computed: {
    showTitle() {
      if (this.FormData.name === '') {
        return '新增部门'
      } else {
        return '编辑部门'
      }
    }
  },
  methods: {
    async getUserSimple() {
      this.peoples = await getUserSimple()
    },
    submitForm() {
      this.$refs.addDept.validate(async (isOk) => {
        if (isOk) {
          if (this.showTitle === '新增部门') {
            await addDepartments({ ...this.FormData, pid: this.treeNode.id })
          } else {
            await updateDepartments({ ...this.FormData })
          }

          // 关闭弹层
          this.$emit('addDpts', false, 0)
          // 如果每次调用addDpts，会导致每次关闭的时候都要发请求,可以传入一个数字让父组件判断什么时候发请求什么时候不发
          // 可以用sync修饰符
          // this.$emit('update:showDialog',false)
          // 在父组件中：<child :showDialog.sync="showDialog"
          // 如果采用这种方法，配合dialog组件的@close事件，在点击确定后dialog关闭，会同时触发close事件，如果在close中写了重置表单，那么这儿不用再写下一行代码
          this.$refs.addDept.resetFields()
        } else {
          this.$message.error('提交失败')
          return false
        }
      })
    },
    cancel() {
      this.$emit('addDpts', false, 1)
      // 重置表单
      this.$refs.addDept.resetFields()
    },
    beforeClose(done) {
      this.$confirm('确认关闭？')
        .then((_) => {
          this.$refs.addDept.resetFields()
          this.$emit('addDpts', false, 1)
          done()
        })
        .catch((_) => {}) // 点击取消的话 啥也不用干 可以不写这段catch代码
    },
    async editDeptsContent(id) {
      this.FormData = await getDepartDetail(id)
    }
  }
}
</script>

<style></style>
